<?php

namespace App\Handlers;

use JohnLui\AliyunOSS;

use DateTime;
use App\Api\Exceptions\ApiCommonException;

class Oss
{
  /* 城市名称：
   *  
   *  经典网络下可选：杭州、上海、青岛、北京、张家口、深圳、香港、硅谷、弗吉尼亚、新加坡、悉尼、日本、法兰克福、迪拜
   *  VPC 网络下可选：杭州、上海、青岛、北京、张家口、深圳、硅谷、弗吉尼亚、新加坡、悉尼、日本、法兰克福、迪拜
   */    
  private $city = '杭州';

  // 经典网络 or VPC
  private $networkType = '经典网络';
  
  private $AccessKeyId = '';
  private $AccessKeySecret = '';
  private $bucketName = '';

  private $ossClient;

  /**
   * 私有初始化 API，非 API，不用关注
   * @param boolean 是否使用内网
   */
  public function __construct($isInternal = false)
  {

      if ($this->networkType == 'VPC' && !$isInternal) {
          throw ApiCommonException::requestParamsErr("VPC 网络下不提供外网上传、下载等功能");
      }

      $this->AccessKeyId = config('alioss.AccessKeyId');
      $this->AccessKeySecret = config('alioss.AccessKeySecret');

      $this->ossClient = AliyunOSS::boot(
          $this->city,
          $this->networkType,
          $isInternal,
          $this->AccessKeyId,
          $this->AccessKeySecret
      );

      $this->bucketName = config('alioss.BucketName');
  }

  /**
   * 使用外网上传文件
   * @param  string bucket名称
   * @param  string 上传之后的 OSS object 名称
   * @param  string 删除文件路径
   * @return boolean 上传是否成功
   */
  public static function publicUpload($ossKey, $filePath, $options = [])
  {
      $self = new self();
      $self->ossClient->setBucket($self->bucketName);
      return $self->ossClient->uploadFile($ossKey, $filePath, $options);
  }

  /**
   * 使用阿里云内网上传文件
   * @param  string bucket名称
   * @param  string 上传之后的 OSS object 名称
   * @param  string 删除文件路径
   * @return boolean 上传是否成功
   */
  public static function privateUpload($ossKey, $filePath, $options = [])
  {
      $self = new self(true);
      $self->ossClient->setBucket($self->bucketName);
      return $self->ossClient->uploadFile($ossKey, $filePath, $options);
  }

  /**
   * 使用外网直接上传变量内容
   * @param  string bucket名称
   * @param  string 上传之后的 OSS object 名称
   * @param  string 删除传的变量
   * @return boolean 上传是否成功
   */
  public static function publicUploadContent($ossKey, $content, $options = [])
  {
      $self = new self();
      $self->ossClient->setBucket($self->bucketName);
      return $self->ossClient->uploadContent($ossKey, $content, $options);
  }

  /**
   * 使用阿里云内网直接上传变量内容
   * @param  string bucket名称
   * @param  string 上传之后的 OSS object 名称
   * @param  string 删除传的变量
   * @return boolean 上传是否成功
   */
  public static function privateUploadContent($ossKey, $content, $options = [])
  {
      $self = new self(true);
      $self->ossClient->setBucket($self->bucketName);
      return $self->ossClient->uploadContent($ossKey, $content, $options);
  }

  /**
   * 使用外网删除文件
   * @param  string bucket名称
   * @param  string 目标 OSS object 名称
   * @return boolean 删除是否成功
   */
  public static function publicDeleteObject($ossKey)
  {
      $self = new self();
      $self->ossClient->setBucket($self->bucketName);
      return $self->ossClient->deleteObject($self->bucketName, $ossKey);
  }

    /**
     * 获取指定文件夹下的所有文件
     * @param $folder_name
     * @return \JohnLui\指定文件夹下的所有文件
     * @throws Exception
     */
  public static function getAllObjectKeyWithPrefix($folder_name)
  {
      $self = new self();
      $self->ossClient->setBucket($self->bucketName);
      return $self->ossClient->getAllObjectKeyWithPrefix($self->bucketName, $folder_name);
  }

    /**
     * 删除指定文件夹下所有文件
     * @param $folder_name
     * @throws Exception
     */
  public static function publicDeleteObjectWithPrefix($folder_name)
  {
      $self = new self();
      $self->ossClient->setBucket($self->bucketName);
      $file_list = $self->ossClient->getAllObjectKeyWithPrefix($self->bucketName, $folder_name);
      if (!empty($file_list)) {
          foreach ($file_list as $value) {
              static::publicDeleteObject($value);
          }
      }
  }

  /**
   * 使用阿里云内网删除文件
   * @param  string bucket名称
   * @param  string 目标 OSS object 名称
   * @return boolean 删除是否成功
   */
  public static function privateDeleteObject($ossKey)
  {
      $self = new self(true);
      $self->ossClient->setBucket($self->bucketName);
      return $self->ossClient->deleteObject($self->bucketName, $ossKey);
  }

    /**
     * 获取公开文件的 URL
     * @param $ossKey
     * @return string
     * @throws Exception
     */
    public static function getPublicObjectURL($ossKey)
    {
        $self = new self();
        $self->ossClient->setBucket($self->bucketName);
        $public_url = $self->ossClient->getPublicUrl($ossKey);
        $public_url = replace_first('http', 'https', $public_url);
        return $public_url;
    }

    /**
     * 获取私有文件的URL，并设定过期时间，如 \DateTime('+1 day')
     * @param $ossKey
     * @param DateTime $expire_time
     * @return mixed
     * @throws Exception
     */
    public static function getPrivateObjectURLWithExpireTime($ossKey, DateTime $expire_time)
    {
        $self = new self();
        $self->ossClient->setBucket($self->bucketName);
        return $self->ossClient->getUrl($ossKey, $expire_time);
    }

    /**
     * 获取所有上传文件key
     * @return array
     * @throws Exception
     */
    public static function getAllObjectKey()
    {
        $self = new self();
        return $self->ossClient->getAllObjectKey($self->bucketName);
    }

    /**
     * 获取指定存储容器下的某个文件的元信息
     * @param $ossKey
     * @return \Aliyun\OSS\Models\OSSObject
     * @throws Exception
     */
    public static function getObjectMeta($ossKey)
    {
        $self = new self();
        return $self->ossClient->getObjectMeta($self->bucketName, $ossKey);
    }
}